#include "messageeditarea.h"
#include "messageshowarea.h"
#include "mainwidget.h"
#include "historymessagewidget.h"
#include "toast.h"
#include "speechrecorder.h"
#include "model/datacenter.h"

#include <QDir>
#include <QFileDialog>
#include <QHBoxLayout>
#include <QScrollBar>

MessageEditArea::MessageEditArea(QWidget *parent)
    : QWidget{parent}
{
    // 1.设置基本属性
    setFixedHeight(200);
    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

    // 2.纵向布局
    QVBoxLayout* vlayout = new QVBoxLayout();
    vlayout->setSpacing(0);
    vlayout->setContentsMargins(10, 0, 15, 13);
    this->setLayout(vlayout);

    // 3.横向布局
    QHBoxLayout* hlayout = new QHBoxLayout();
    hlayout->setSpacing(0);
    hlayout->setContentsMargins(0, 0, 0, 0);
    hlayout->setAlignment(Qt::AlignLeft | Qt::AlignTop);
    vlayout->addLayout(hlayout);

    QString buttonStyle = "QPushButton { background-color: rgb(245, 245, 245); border: none; } "
                          "QPushButton:pressed { background-color: rgb(255, 255, 255);}";
    QSize buttonSize(35, 35);
    QSize iconSize(25, 25);

    auto makeBtn = [&](const QString& imagePath){
        QPushButton* btn = new QPushButton();
        btn->setFixedSize(buttonSize);
        btn->setIconSize(iconSize);
        btn->setIcon(QIcon(imagePath));
        btn->setStyleSheet(buttonStyle);
        hlayout->addWidget(btn);
        return btn;
    };

    // 4个功能按钮
    sendImageBtn = makeBtn(":/resource/image/image.png");
    sendFileBtn = makeBtn(":/resource/image/file.png");
    sendSpeechBtn = makeBtn(":/resource/image/sound.png");
    showHistoryBtn = makeBtn(":/resource/image/history.png");

    // 5.多行编辑区
    textEdit = new QPlainTextEdit();
    textEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    textEdit->setStyleSheet("QPlainTextEdit { border: none; background-color: transparent; font-size: 14px; padding: 10px; } ");
    utils::WidgetUtil::applyScrollStyle(textEdit);
    vlayout->addWidget(textEdit);

    // 6.消息发送按钮
    sendBtn = new QPushButton();
    sendBtn->setText("发送");
    sendBtn->setFixedSize(100, 35);
    QString style = "QPushButton { font-size: 16px; color: rgb(7, 193, 96); border: none; "
                    "background-color: rgb(233, 233, 233); border-radius: 5px; }";
    style += "QPushButton:hover { background-color: rgb(210, 210, 210); }";
    style += "QPushButton:pressed { background-color: rgb(198, 198, 198);}";
    sendBtn->setStyleSheet(style);
    vlayout->addWidget(sendBtn, 0, Qt::AlignRight | Qt::AlignVCenter);

    // 7.信号槽注册
    initSignalSlot();
}

QPushButton* MessageEditArea::getSendBtn()
{
    return sendBtn;
}

void MessageEditArea::initSignalSlot()
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();

    ///////////////// 关联历史消息信号槽
    connect(showHistoryBtn, &QPushButton::clicked, this, [=](){
        if(dataCenter->getCurrentChatSessionId().isEmpty()) {
            return;
        }
        HistoryMessageWidget* historyMessageWidget = new HistoryMessageWidget(this);
        historyMessageWidget->exec();
    });

    ///////////////// 关联 "发送消息" 信号槽
    connect(dataCenter, &model::DataCenter::sendMessageDone, this, &MessageEditArea::addSelfMessage);
    connect(sendBtn, &QPushButton::clicked, this, &MessageEditArea::sendTextMessage);

    ///////////////// 关联 "收到消息" 信号槽
    connect(dataCenter, &model::DataCenter::receiveMessageDone, this, &MessageEditArea::addOtherMessage);

    ///////////////// 关联发送图片信号槽
    connect(sendImageBtn, &QPushButton::clicked, this, &MessageEditArea::onClickedSendImageBtn);

    ///////////////// 关联发送文件信号槽
    connect(sendFileBtn, &QPushButton::clicked, this, &MessageEditArea::onClickedSendFileBtn);

    ///////////////// 关联录制发送语音信号槽
    SpeechRecorder* speechRecorder = SpeechRecorder::getInstance();
    connect(speechRecorder, &SpeechRecorder::speechRecordDone, this, &MessageEditArea::speechRecordDoneHandle);
    connect(sendSpeechBtn, &QPushButton::pressed, this, &MessageEditArea::onPressedSendSpeechBtn);
    connect(sendSpeechBtn, &QPushButton::released, this, &MessageEditArea::onReleasedSendSpeechBtn);
}

void MessageEditArea::sendTextMessage()
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    if(dataCenter->getCurrentChatSessionId().isEmpty()) {
        sendBtn->setEnabled(false);
        return;
    }

    // 过滤无效空格数据
    const QString& content = textEdit->toPlainText().trimmed();
    if(content.isEmpty()) {
        LOG(LL_DEBUG, "当前未选中会话，无法发送消息.");
        Toast::showMessage("不能发送空白消息");
        return;
    }

    // 清空无效数据
    textEdit->setPlainText("");

    dataCenter->sendTextMessageAsync(content);
}

void MessageEditArea::addSelfMessage(model::MessageType messageType, const QByteArray& content, const QString& extraInfo)
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    const QString& chatSessionId = dataCenter->getCurrentChatSessionId();

    // 1.构造消息对象
    model::Message msg = model::Message::makeMessage(messageType, chatSessionId, *dataCenter->getSelfInfo(), content, extraInfo);
    dataCenter->addMessage(msg);

    // 2.同步到展示区
    MainWidget* mainWidget = MainWidget::getInstance();
    MessageShowArea* messageShowArea = mainWidget->getMessageShowArea();
    messageShowArea->addMessage(false, msg);

    // 3.同步滚动条
    messageShowArea->scrollToEndLater(50);

    // 4.同步会话列表的最近消息
    emit dataCenter->updateLastMessage(chatSessionId);
}

void MessageEditArea::addOtherMessage(const model::Message& message)
{
    MainWidget* mainWidget = MainWidget::getInstance();
    MessageShowArea* messageShowArea = mainWidget->getMessageShowArea();

    messageShowArea->addMessage(true, message);
    messageShowArea->scrollToEndLater(200);

    Toast::showMessage("收到一条新的消息");
}

void MessageEditArea::onClickedSendImageBtn()
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    if(dataCenter->getCurrentChatSessionId().isEmpty()) {
        Toast::showMessage("请先选择要发送图片的会话");
        return;
    }

    QString filter = "Image Files (*.png *.jpg *.jpeg)";
    QString imagePath = QFileDialog::getOpenFileName(this, "选择图片", QDir::homePath(), filter);   // 默认打开用户目录
    if(imagePath.isEmpty()) {
        return;
    }

    QByteArray imageContent = utils::FileUtil::loadByteArrayFromFile(imagePath);

    dataCenter->sendImageMessageAsync(imageContent);
}

void MessageEditArea::onClickedSendFileBtn()
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    if(dataCenter->getCurrentChatSessionId().isEmpty()) {
        Toast::showMessage("请先选择要发送文件的会话");
        return;
    }

    QString filter = "Image Files (*)";
    QString filePath = QFileDialog::getOpenFileName(this, "选择文件", QDir::homePath(), filter);
    if(filePath.isEmpty()) {
        return;
    }

    // TODO: 大文件采用 “分片传输”
    QByteArray fileContent = utils::FileUtil::loadByteArrayFromFile(filePath);

    QFileInfo fileInfo(filePath);
    const QString& fileName = fileInfo.fileName();

    dataCenter->sendFileMessageAsync(fileName, fileContent);
}

void MessageEditArea::onPressedSendSpeechBtn()
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    if(dataCenter->getCurrentChatSessionId().isEmpty()) {
        Toast::showMessage("请先选择要发送语音的会话");
        return;
    }

    // 1.切换图标状态
    sendSpeechBtn->setIcon(QIcon(":/resource/image/sound_active.png"));

    SpeechRecorder* speechRecorder = SpeechRecorder::getInstance();
    speechRecorder->startRecord();
}

void MessageEditArea::onReleasedSendSpeechBtn()
{
    // 1.切换图标状态
    sendSpeechBtn->setIcon(QIcon(":/resource/image/sound.png"));

    SpeechRecorder* speechRecorder = SpeechRecorder::getInstance();
    speechRecorder->stopRecord();
}

void MessageEditArea::speechRecordDoneHandle(const QString& path)
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    QByteArray content = utils::FileUtil::loadByteArrayFromFile(path);
    if(content.isEmpty()) {
        LOG(LL_ERROR, "语音文件加载为空.");
        return;
    }
    dataCenter->sendSpeechMessageAsync(content);
}
